home *** CD-ROM | disk | FTP | other *** search
/ Ray Dream Studio 5 / Ray Dream.iso / pc / DreamSDK / Windows / SAMPLES / DEFORMER / DEFX / COMDEFX.CPP next >
Encoding:
C/C++ Source or Header  |  1997-07-11  |  11.7 KB  |  383 lines

  1. // Copyright (c)1995 Ray Dream, Inc. All Rights Reserved.
  2. /* $Id: COMDefX.cpp 1.7 1997/05/12 19:01:14 damien Exp $ */
  3.  
  4. ////////////////////////////////////////////////////////////////////////
  5. //  Deformer Example                                                  //
  6. //--------------------------------------------------------------------//
  7. //   Implementation of the Deformer Interface                         //
  8. //////////////////////////////////////////////////////////////////////// 
  9.  
  10.  
  11. #ifndef __COMDEFX__
  12. #include "COMDEFX.h"
  13. #endif
  14.  
  15. #ifndef __DEFXDLL__
  16. #include "DEFXDLL.h"
  17. #endif
  18.  
  19. #ifndef __3DCOFAIL__
  20. #include "3DCoFail.h"
  21. #endif
  22.  
  23. #ifndef __I3DSHUTI__
  24. #include "I3DShUti.h"
  25. #endif
  26.  
  27. /*#ifndef __3DBTOOLS__
  28. #include "3DbTools.h"
  29. #endif*/
  30.  
  31. #ifndef __ISHFMESH__
  32. #include "IShFMesh.h"
  33. #endif
  34.  
  35. #undef INTERFACE
  36. #define INTERFACE Deformer
  37. // Constructor / Destructor of the C++ Object :
  38. Deformer::Deformer() {
  39.   fCRef=0; // Reference Counter
  40.   
  41.   // Data initialisation :
  42.   fData.fMinSize = 1.0; // 4 inches
  43.   fData.fExplosionFactor = 0.0;
  44.   fData.fGravityOrNotGravity = FALSE;
  45.   fData.fFloor = 0.0;
  46.   fData.fGravityCoef = 1.0;
  47.  
  48.   fData.fBoundingBox.fMin[0] = 0.0;
  49.   fData.fBoundingBox.fMin[1] = 0.0;
  50.   fData.fBoundingBox.fMin[2] = 0.0;
  51.   fData.fBoundingBox.fMax[0] = 0.0;
  52.   fData.fBoundingBox.fMax[1] = 0.0;
  53.   fData.fBoundingBox.fMax[2] = 0.0;
  54.   }
  55.   
  56. Deformer::~Deformer() {
  57.   global_count_Obj--; 
  58.   }
  59.   
  60. // IUnknown Interface :
  61. HRESULT Deformer::QueryInterface(THIS_ REFIID riid,LPVOID* ppvObj) {
  62.   *ppvObj=NULL;
  63.   
  64.   // The Deformer knows the interfaces of the parent Objects
  65.   if (IsEqualIID(riid, IID_IUnknown))
  66.     *ppvObj=(LPVOID)this;
  67.   else if (IsEqualIID(riid, IID_I3DExDeformer2))
  68.     *ppvObj=(LPVOID)(I3DExDeformer2*)this;
  69.   else if (IsEqualIID(riid, IID_I3DExDataExchanger))
  70.     *ppvObj=(LPVOID)(I3DExDataExchanger*)this;
  71.   else if (IsEqualIID(riid, IID_I3DExtension))
  72.     *ppvObj=(LPVOID)(I3DExtension*)this;
  73.     
  74.   // we must add reference if we return an interface
  75.   if (*ppvObj!=NULL) {
  76.     ((LPUNKNOWN)*ppvObj)->AddRef();
  77.     return NOERROR;
  78.     }
  79.   else {
  80.     return ResultFromScode(E_NOINTERFACE);
  81.     }
  82.   }
  83.  
  84. ULONG Deformer::AddRef(THIS) {
  85.   return fCRef++;
  86.   }
  87.   
  88. ULONG Deformer::Release(THIS) {
  89.   ULONG UnreleaseObject=fCRef--;
  90.   
  91.   if (fCRef==0)
  92.      delete this; // No reference left, so destroy the object
  93.   
  94.   return UnreleaseObject;
  95.   // local variable used, because fCRef can be destroyed before.
  96.   }
  97.   
  98. // I3DExtension methods :
  99. I3DExtension* Deformer::Clone(THIS) {
  100.   Deformer* theClone = new Deformer;
  101.   if (theClone) {
  102.     theClone->AddRef();
  103.     theClone->fData=fData; // copy the DeformerData
  104.     }                               
  105.   return (I3DExtension*)theClone;
  106.   }   
  107.  
  108. HRESULT Deformer::ShellUtilitiesInit(THIS_ IShUtilities* shellUtilities) {
  109.   InitCoFailure(shellUtilities);
  110.   return NOERROR;
  111.   }
  112.  
  113. // I3DExDataExchanger methods :
  114. ExtensionDataMap* Deformer::GetExtensionDataMap(THIS) {
  115.   return NULL;
  116.   }
  117.  
  118. void* Deformer::GetExtensionDataBuffer(THIS) {
  119.   return &fData; // used by the shell to set the new parameters
  120.   }
  121.   
  122. HRESULT Deformer::ExtensionDataChanged(THIS) {
  123.   return NOERROR;
  124.   }
  125.  
  126. HRESULT Deformer::HandleEvent(THIS_ ULONG SourceID) {
  127.   return ResultFromScode(E_NOTIMPL);
  128.   }
  129.  
  130. short Deformer::GetResID(THIS) {
  131.   return 143; // this is the view ID in the resource file.
  132.   }
  133.   
  134. // I3DExDeformer methods :
  135.  
  136. HRESULT Deformer::SetBBox(THIS_ BOX3D *bbox) {
  137.   fData.fBoundingBox=*bbox;
  138.   return NOERROR;
  139.     }
  140.  
  141. HRESULT Deformer::DeformPoint(THIS_ VECTOR3D* point,VECTOR3D* result) {
  142.   VECTOR3D Translate;
  143.   int i;
  144.   Translate[0] = (*point)[0] * fData.fExplosionFactor;
  145.   Translate[1] = (*point)[1] * fData.fExplosionFactor;
  146.   if (!fData.fGravityOrNotGravity) {
  147.     Translate[2] = (*point)[2] * fData.fExplosionFactor;
  148.     }
  149.   else {
  150.     NUM3D a = 9.8;
  151.     if ((*point)[2]<=fData.fFloor) 
  152.       Translate[2]=0.0;
  153.     else {
  154.       Translate[2]=(*point)[2] * fData.fExplosionFactor - fData.fGravityCoef * (fData.fExplosionFactor * fData.fExplosionFactor);
  155.       }
  156.     if ((*point)[2]+Translate[2]<fData.fFloor) {
  157.       Translate[2]=fData.fFloor - (*point)[2];
  158.       }
  159.     }
  160.     for (i=0; i<3; i++) {
  161.         (*result)[i] = (*point)[i] + Translate[i];
  162.         }
  163. /*    (*result)[0] = (*point)[0] * fData.fExplosionFactor;
  164.     (*result)[1] = (*point)[1] * fData.fExplosionFactor;
  165.     (*result)[2] = (*point)[2] * fData.fExplosionFactor; // by Default this deformer change the scale*/
  166.   return NOERROR;
  167.     }
  168.  
  169. // EVX calls for Mac/EVX case
  170. extern "C" {
  171. void  OLXIteratorReset(IShIterator *iter);
  172. void * OLXIteratorNext(IShIterator *iter);
  173. void * OLXIteratorGetInfo(IShIterator *iter,short index);
  174. void  OLXIteratorDelete(IShIterator *iter);
  175.     }
  176.  
  177. // Split a Facet between point p1 and p3
  178. //   p1____________ p3
  179. //     \    |    /
  180. //      \ f1|f2 /
  181. //       \  |  /
  182. //        \ | /
  183. //         \|/
  184. //          p2
  185. void SplitFacet(const FACET3D *f0,FACET3D *f1,FACET3D *f2,short p1, short p2, short p3) {
  186.   f1->fVertices[0] = f0->fVertices[p1]; // Copy normal/UV/point
  187.   f1->fVertices[1] = f0->fVertices[p2];
  188.   f1->fVertices[2].fVertex[0] = (f0->fVertices[p1].fVertex[0] + f0->fVertices[p3].fVertex[0])/2.0;
  189.   f1->fVertices[2].fVertex[1] = (f0->fVertices[p1].fVertex[1] + f0->fVertices[p3].fVertex[1])/2.0;
  190.   f1->fVertices[2].fVertex[2] = (f0->fVertices[p1].fVertex[2] + f0->fVertices[p3].fVertex[2])/2.0;
  191.   f1->fVertices[2].fNormal[0] = (f0->fVertices[p1].fNormal[0] + f0->fVertices[p3].fNormal[0])/2.0;
  192.   f1->fVertices[2].fNormal[1] = (f0->fVertices[p1].fNormal[1] + f0->fVertices[p3].fNormal[1])/2.0;
  193.   f1->fVertices[2].fNormal[2] = (f0->fVertices[p1].fNormal[2] + f0->fVertices[p3].fNormal[2])/2.0;
  194.   f1->fVertices[2].fUV[0] =(f0->fVertices[p1].fUV[0] + f0->fVertices[p3].fUV[0])/2;
  195.   f1->fVertices[2].fUV[1] =(f0->fVertices[p1].fUV[1] + f0->fVertices[p3].fUV[1])/2;
  196.   f1->fUVSpace = f2->fUVSpace = f0->fUVSpace;
  197.   f2->fVertices[0] = f0->fVertices[p2];
  198.   f2->fVertices[1] = f0->fVertices[p3];
  199.   f2->fVertices[2] = f1->fVertices[2];
  200.   }
  201.  
  202. // The criteria to split a facet is the longest size on the X axis
  203. void SplitFacetX(const FACET3D *aFacet,FACET3D *f1,FACET3D *f2) {
  204.   short p1,p2,p3;
  205.   NUM3D dx1,dx2,dx3;
  206.   dx1 = aFacet->fVertices[1].fVertex[0] - aFacet->fVertices[0].fVertex[0];
  207.   dx2 = aFacet->fVertices[2].fVertex[0] - aFacet->fVertices[1].fVertex[0];
  208.   dx3 = aFacet->fVertices[0].fVertex[0] - aFacet->fVertices[2].fVertex[0];
  209.  
  210.   if (dx1<0.0) dx1= -dx1;
  211.   if (dx2<0.0) dx2= -dx2;
  212.   if (dx3<0.0) dx3= -dx3;
  213.  
  214.   if ((dx1>=dx2)&&(dx1>=dx3)) {
  215.     p1=1;p2=2;p3=0;
  216.     // split the facet between p1 and p3
  217.     }
  218.   else if ((dx2>=dx1)&&(dx2>=dx3)) {
  219.     p1=2;p2=0;p3=1;
  220.     // split the facet between p1 and p3
  221.     }
  222.   else {
  223.     p1=0;p2=1;p3=2;
  224.     // split the facet between p1 and p3
  225.     }
  226.   SplitFacet(aFacet,f1,f2,p1,p2,p3);  
  227.   }
  228.  
  229. // The criteria to split a facet is the longest size on the Y axis
  230. void SplitFacetY(const FACET3D *aFacet,FACET3D *f1,FACET3D *f2) {
  231.   short p1,p2,p3;
  232.   NUM3D dy1,dy2,dy3;
  233.   dy1 = aFacet->fVertices[1].fVertex[1] - aFacet->fVertices[0].fVertex[1];
  234.   dy2 = aFacet->fVertices[2].fVertex[1] - aFacet->fVertices[1].fVertex[1];
  235.   dy3 = aFacet->fVertices[0].fVertex[1] - aFacet->fVertices[2].fVertex[1];
  236.  
  237.   if (dy1<0.0) dy1= -dy1;
  238.   if (dy2<0.0) dy2= -dy2;
  239.   if (dy3<0.0) dy3= -dy3;
  240.  
  241.   if ((dy1>=dy2)&&(dy1>=dy3)) {
  242.     p1=1;p2=2;p3=0;
  243.     // split the facet between p1 and p3
  244.     }
  245.   else if ((dy2>=dy1)&&(dy2>=dy3)) {
  246.     p1=2;p2=0;p3=1;
  247.     // split the facet between p1 and p3
  248.     }
  249.   else {
  250.     p1=0;p2=1;p3=2;
  251.     // split the facet between p1 and p3
  252.     }
  253.   SplitFacet(aFacet,f1,f2,p1,p2,p3);  
  254.   }
  255.  
  256. // The criteria to split a facet is the longest size on the Z axis
  257. void SplitFacetZ(const FACET3D *aFacet,FACET3D *f1,FACET3D *f2) {
  258.   short p1,p2,p3;
  259.   NUM3D dz1,dz2,dz3;
  260.   dz1 = aFacet->fVertices[1].fVertex[2] - aFacet->fVertices[0].fVertex[2];
  261.   dz2 = aFacet->fVertices[2].fVertex[2] - aFacet->fVertices[1].fVertex[2];
  262.   dz3 = aFacet->fVertices[0].fVertex[2] - aFacet->fVertices[2].fVertex[2];
  263.  
  264.   if (dz1<0.0) dz1= -dz1;
  265.   if (dz2<0.0) dz2= -dz2;
  266.   if (dz3<0.0) dz3= -dz3;
  267.  
  268.   if ((dz1>=dz2)&&(dz1>=dz3)) {
  269.     p1=1;p2=2;p3=0;
  270.     // split the facet between p1 and p3
  271.     }
  272.   else if ((dz2>=dz1)&&(dz2>=dz3)) {
  273.     p1=2;p2=0;p3=1;
  274.     // split the facet between p1 and p3
  275.     }
  276.   else {
  277.     p1=0;p2=1;p3=2;
  278.     // split the facet between p1 and p3
  279.     }
  280.   SplitFacet(aFacet,f1,f2,p1,p2,p3);  
  281.   }
  282.  
  283. // Verify Size of the facet to split it if necessary and move it.
  284. void Deformer::explodeFacet(const FACET3D *aFacet, IShFacetMeshAccumulator* accu, short level) {
  285.   short i,j;
  286.   NUM3D sx,sy,sz;
  287.   // Calcul size of the Facet
  288.   BOX3D facetbb;
  289.   for(i=0;i<3;i++) facetbb.fMin[i]=facetbb.fMax[i]=aFacet->fVertices[0].fVertex[i];
  290.   for(i=1;i<3;i++) {
  291.     for (j=0;j<3;j++) {
  292.       if (facetbb.fMin[j]>aFacet->fVertices[i].fVertex[j])
  293.         facetbb.fMin[j]=aFacet->fVertices[i].fVertex[j];
  294.       if (facetbb.fMax[j]<aFacet->fVertices[i].fVertex[j])
  295.         facetbb.fMax[j]=aFacet->fVertices[i].fVertex[j];
  296.       }
  297.     }
  298.   sx = facetbb.fMax[0]-facetbb.fMin[0];
  299.   sy = facetbb.fMax[1]-facetbb.fMin[1];
  300.   sz = facetbb.fMax[2]-facetbb.fMin[2];
  301.  
  302.   if (fData.fMinSize<1.0/16.0 || level>SPLITMAX) {
  303.         accu->AddFacet(aFacet);
  304.     }
  305.   else if (sx>fData.fMinSize) {
  306.     FACET3D f1,f2;
  307.     SplitFacetX(aFacet, &f1, &f2);
  308.     explodeFacet(&f1, accu, level+1);
  309.     explodeFacet(&f2, accu, level+1);    
  310.     }
  311.   else if (sy>fData.fMinSize) {
  312.     FACET3D f1,f2;
  313.     SplitFacetY(aFacet, &f1, &f2);
  314.     explodeFacet(&f1, accu, level+1);
  315.     explodeFacet(&f2, accu, level+1);
  316.     }
  317.   else if (sz>fData.fMinSize) {
  318.     FACET3D f1,f2;
  319.     SplitFacetZ(aFacet, &f1, &f2);
  320.     explodeFacet(&f1, accu, level+1);
  321.     explodeFacet(&f2, accu, level+1);
  322.     }
  323.   else {
  324.         FACET3D movedFacet=*aFacet;
  325.     moveFacet(&movedFacet);
  326.         accu->AddFacet(&movedFacet);
  327.     }
  328.   }
  329.  
  330. void Deformer::moveFacet(FACET3D *aFacet) {
  331.   VECTOR3D BaryCentre;
  332.   VECTOR3D Translate;
  333.   int i;
  334.   for (i=0; i<3; i++) {
  335.         BaryCentre[i] = aFacet->fVertices[0].fVertex[i]
  336.                   + aFacet->fVertices[1].fVertex[i]
  337.                                 + aFacet->fVertices[2].fVertex[i];
  338.       BaryCentre[i] /= 3.0;
  339.     }
  340.   Translate[0] = BaryCentre[0] * fData.fExplosionFactor;
  341.   Translate[1] = BaryCentre[1] * fData.fExplosionFactor;
  342.   if (!fData.fGravityOrNotGravity) {
  343.     Translate[2] = BaryCentre[2] * fData.fExplosionFactor;
  344.     }
  345.   else {
  346.     NUM3D a = 9.8;
  347.     if (BaryCentre[2]<=fData.fFloor) 
  348.       Translate[2]=0.0;
  349.     else {
  350.       Translate[2]=BaryCentre[2] * fData.fExplosionFactor - fData.fGravityCoef * (fData.fExplosionFactor * fData.fExplosionFactor);
  351.       }
  352.     if (BaryCentre[2]+Translate[2]<fData.fFloor) {
  353.       Translate[2]=fData.fFloor - BaryCentre[2];
  354.       }
  355.     }
  356.     for (i=0; i<3; i++) {
  357.         aFacet->fVertices[0].fVertex[i] += Translate[i];
  358.         aFacet->fVertices[1].fVertex[i] += Translate[i];
  359.         aFacet->fVertices[2].fVertex[i] += Translate[i];
  360.         }
  361.   }
  362.  
  363. HRESULT Deformer::DeformFacetMesh(NUM3D lod,const FacetMesh &in,FacetMesh &out) {
  364.     IShFacetMeshAccumulator* accu;
  365.     gShellUtilities->CoCreateInstance(CLSID_StandardFacetMeshAccumulator, NULL, CLSCTX_INPROC_SERVER, IID_IShFacetMeshAccumulator, (LPVOID*)&accu);
  366.     IShFacetMeshIterator* iter;
  367.     gShellUtilities->CoCreateInstance(CLSID_StandardFacetMeshIterator, NULL, CLSCTX_INPROC_SERVER, IID_IShFacetMeshIterator, (LPVOID*)&iter);
  368.     iter->Initialize(&in);
  369.     while (iter->Next()) {
  370.         explodeFacet(&iter->GetFacet(), accu);
  371.         }
  372.     iter->Release();
  373.     accu->MakeFacetMesh(out);
  374.     accu->Release();
  375.   return S_OK;
  376.   }
  377.  
  378. HRESULT Deformer::DeformBBox(const BOX3D &in, BOX3D &out) {
  379.     DeformPoint((VECTOR3D*)&in.fMin, &out.fMin);
  380.     DeformPoint((VECTOR3D*)&in.fMax, &out.fMax);
  381.     return S_OK;
  382.     }
  383.